home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Testing & Debugging / Mac OS Development Toolkit / Automation Essentials 2.3.0 / Host Automation Folder / VU External Tool libs / AEPost.vuLib next >
Encoding:
Text File  |  1998-03-19  |  17.5 KB  |  411 lines  |  [TEXT/MPS ]

  1. #########################################################################
  2. #########################################################################
  3. ##                     Copyright © 1993-1997 Apple Computer, Inc.
  4. ##                                All rights reserved
  5. #########################################################################
  6. #########################################################################
  7. #    
  8. #    Library:        AEPost.vulib
  9. #    
  10. #    Version:        1.0.0
  11. #    
  12. #    Description:    This file contains support tasks for using AEPost 
  13. #                    from a VU script. 
  14. #                    
  15. #                    AEPost is an external tool for sending messages 
  16. #                    between VU scripts, AppleScript scripts, and any
  17. #                    other Apple Event savvy application. A message
  18. #                    is a list of simple data types, namely strings,
  19. #                    integers, Booleans, and other lists. These types
  20. #                    appear the same to VU and AppleScript, making 
  21. #                    real-time communication between them easy.
  22. #                    
  23. #                    To allow asynchronous sending and receiving, the
  24. #                    messages are held in "mailboxes". Each mailbox has 
  25. #                    a unique ID. Mailbox IDs are lists of the same 
  26. #                    design as a message, but usually much shorter.
  27. #                    Each script can "own" multiple mailboxes at any 
  28. #                    given time, although most use only one. 
  29. #                    
  30. #                    There is no security in AEPost 1.0. The goal is to 
  31. #                    create a useful tool for automation, not a private 
  32. #                    e-mail system. All messages are visible if you know 
  33. #                    the mailbox ID.
  34. #                    
  35. #                    Messages are sent to mailbox IDs and received 
  36. #                    from mailbox IDs. Sending and receiving scripts 
  37. #                    have no knowledge of each other. This can lead to 
  38. #                    interesting "failures" where the sender tries to 
  39. #                    send before the receiver creates its mailbox. 
  40. #                    
  41. #                    To alleviate this problem, AEPost allows 
  42. #                    senders and receivers to specify a timeout value 
  43. #                    for failures instead of failing immediately. See 
  44. #                    the individual tasks for the definitions of 
  45. #                    these timeouts. 
  46. #                    
  47. #                    Before using AEPost, your VU script must call 
  48. #                    InitMessages(). To send a message to a mailbox ID, 
  49. #                    use SendMessage(), and to retreive a message (or 
  50. #                    several messages) use ReceiveMessage().
  51. #    
  52. #    Contains:
  53. #        VU External Tool Service Declarations
  54. #        SendMessage()
  55. #        ReceiveMessage()
  56. #        InitMessages()
  57. #    
  58. #    History:
  59. #        10/30/94    SBR        First built with Echo service
  60. #        08/13/95    SBR        Added to Clouseau projector database.
  61. #        01/28/97    JAS        Added service GetThreads to this file.
  62. #                            Added descriptions for ReadAllMail and GetThreads.
  63. #
  64. #    Version    When        Who    What
  65. #    1.2.0    01/28/97    JAS    Added 'vers' resources to library.
  66. #                            These should always match tool version when tool is revved.
  67. #    
  68. #########################################################################
  69. #########################################################################
  70.  
  71. tool AEPost s:'MsgS'
  72. begin
  73.     # Services specific to AEPost:
  74.     
  75.     # To Echo a list after a number of ticks, in a new thread 
  76.     # first parameter is the value or list of values to echo 
  77.     # second parameter is the number of ticks to pause before returning
  78.     # third parameter is Boolean: 
  79.     #        true means beep entering and leaving ProcessRequest()
  80.     #        false means do not 
  81.     # return value should be equal to first parameter except when:
  82.     #        symbol and descriptor parameters are turned into strings by VU
  83.     #        integers are sent to the tool as long or short based on VU version
  84.     #        longs are sent to the script as long or string based on VU version
  85.     Service    "EchoThread"( 'undefined', 'integer', 'symbol', 'integer' ) return 'undefined';
  86.     
  87.     # To Echo a list after a number of ticks, in the RequestDispatcher thread 
  88.     # same as Echo service except this one is non-threaded
  89.     Service    "EchoNoThread"( 'undefined', 'integer', 'symbol', 'integer' ) return 'undefined';
  90.     
  91.     # To set the number of ticks given to WaitNextEvent() in the tool
  92.     # Only affects the tool when it is in the background
  93.     # returns the previous value
  94.     Service    "SetSleepTicks"( 'integer' ) return 'integer';
  95.     
  96.     # To get messages from a Mailbox in the external tool (create Mailbox if needed)
  97.     # 1st parameter is a list, the ReceiverID
  98.     # 2nd parameter is a list, the SenderID, to filter messages to be received
  99.     # 3rd parameter is a Boolean, true to receive all messages (even if filtered)
  100.     #                                 false to receive one message at a time
  101.     # 4th parameter is a Boolean, true to delete the Mailbox when service returns
  102.     #                                 false to let the Mailbox stay
  103.     # returns the message(s) received (a list):
  104.     #    if Sender ID defined and 2nd param true:
  105.     #        returns contentsList 
  106.     #    if Sender ID defined and 2nd param false:
  107.     #        returns { contentsList1, ..., contentsListn }
  108.     #    if Sender ID undefined and 2nd param true:
  109.     #        returns { { SenderID1, contentsList1 }, ..., { SenderIDn, contentsListn } }
  110.     #    if Sender ID undefined and 2nd param false:
  111.     #        returns { SenderID, contentsList } 
  112.     Service    "MsgReceive"( 'list', 'list', 'symbol', 'symbol'  ) return 'undefined';
  113.     
  114.     # To get messages from a Mailbox in the external tool (create Mailbox if needed)
  115.     # 1st parameter is a list, the ReceiverID
  116.     # 2nd parameter is a list, the SenderID, to filter messages to be received
  117.     # 3rd parameter is a Boolean, true to receive all messages (even if filtered)
  118.     #                                 false to receive one message at a time
  119.     # 4th parameter is a Boolean, true to delete the Mailbox when service returns
  120.     #                                 false to let the Mailbox stay
  121.     # 5th parameter is an Integer,    >0 is seconds to wait until a message is received
  122.     #                                 =0 to return immediately whether message or not
  123.     # returns the message(s) received (a list):
  124.     #    if Sender ID defined and 2nd param true:
  125.     #        returns contentsList 
  126.     #    if Sender ID defined and 2nd param false:
  127.     #        returns { contentsList1, ..., contentsListn }
  128.     #    if Sender ID undefined and 2nd param true:
  129.     #        returns { { SenderID1, contentsList1 }, ..., { SenderIDn, contentsListn } }
  130.     #    if Sender ID undefined and 2nd param false:
  131.     #        returns { SenderID, contentsList } 
  132.     Service    "MsgReceiveThread"( 'list', 'list', 'symbol', 'symbol', 'integer'  ) return 'undefined';
  133.     
  134.     # To send a message to an existing Mailbox
  135.     # 1st parameter is the ReceiverID list
  136.     # 2nd parameter is the SenderID list
  137.     # 3rd parameter is the contents list
  138.     # 4th parameter is a Boolean: 
  139.     #    true means create a Mailbox with ID = ReceiverID (for the expected reply)
  140.     #    false means do not create a Mailbox (no reply expected)
  141.     # returns true if the message was sent, otherwise returns error value
  142.     Service    "MsgSend"( 'list', 'list', 'list', 'symbol' ) return 'undefined';
  143.     
  144.     # To send a message to Mailbox that may not exist yet
  145.     # 1st parameter is the ReceiverID list
  146.     # 2nd parameter is the SenderID list
  147.     # 3rd parameter is the contents list
  148.     # 4th parameter is a Boolean: 
  149.     #    true means create a Mailbox with ID = ReceiverID (for the expected reply)
  150.     #    false means do not create a Mailbox (no reply expected)
  151.     # 5th parameter is an integer (WaitForSend): 
  152.     #    >0 is seconds to wait for receiver mailbox to appear
  153.     #    =0 means return error if receiver mailbox is not already there
  154.     # 6th parameter is an integer (WaitForReceipt): 
  155.     #    >0 is seconds to wait for receiver to read the message
  156.     #    =0 means do not wait for receiver to read the message
  157.     # 7th parameter is an integer (WaitForReply): 
  158.     #    >0 is seconds to wait for one message from the receiver (assumed to be the reply)
  159.     #    =0 means do not wait for a message from the receiver (use MsgReceive service later)
  160.     # returns true if the message was sent, otherwise returns error value
  161.     Service    "MsgSendThread"( 'list', 'list', 'list', 'symbol',
  162.                                     'integer', 'integer', 'integer' ) return 'undefined';
  163.     
  164.     # Read all mail in all mailboxes
  165.     # retuns a list of all mailboxes and their contents (if any)
  166.     # Each mailbox in the returned list is shown as follows:
  167.     #
  168.     #    {{mailboxID},{messageID,receiptRequested,{receiverID},{senderID},{messageContents}}}
  169.     #
  170.     #    mailboxID            List. The ID of this mailbox (receiver)
  171.     #    messageID            Integer. The ID of this message. Used internally.
  172.     #    receiptRequested    Boolean. True if a receipt requested.
  173.     #    receiverID            List. The receiverID the message was sent to. Should match     mailboxID.
  174.     #    senderID            List. The ID of the message sender.
  175.     #    messageContents        List. The message itself.
  176.     #
  177.     # If there are no messages in a mailbox only the mailboxID is returned in the list:
  178.     #    {{mailboxID}}
  179.     #
  180.     # Note: Calling ReadAllMail returns copies of the messages currently in all mailboxes,
  181.     # it does not remove the messages.
  182.     #
  183.     Service "ReadAllMail" () return 'list';
  184.     
  185.     # returns a list of all threads that currently exist in the tool
  186.     #
  187.     # Each item in returnedValue has the form:
  188.     #    { threadID, threadState, {threadOwnerInfo} }
  189.     #    
  190.     #    The threadID is the ID assigned by the Thread Manager.
  191.     #    The threadState is the Thread Manager state converted to a string.
  192.     #    The threadOwnerInfo is a list. It contains:
  193.     #        {threadName, {threadParameters}, threadStatus}
  194.     #    
  195.     #        The threadName is the threaded service's name for this request, 
  196.     #        or it may be "Application" indicating the Application (main) thread, 
  197.     #        or it may be "RequestDispatcher" indicating the RequestDispatcher thread. 
  198.     #        (For more information see "VU Tool Template Design Notes.")
  199.     #    
  200.     #        The threadParameters is a list of the parameters for this request.
  201.     #        Currently "Application" and "RequestDispatcher" have empty lists
  202.     #        for their threadParameters.
  203.     #    
  204.     #    The threadStatus is an optional string that may be set at any time by
  205.     #    the code currently executing in the thread. (For more information on
  206.     #    designing external tools see "VU Tool Template Design Notes.") 
  207.     #
  208.     Service "GetThreads" () return 'list';
  209.         
  210.     # To check for tool memory leaks - calls FreeMem() Memory Manager funtion. 
  211.     Service    "FreeMemory"( ) return 'integer';
  212.     
  213. end;
  214.  
  215.  
  216.  
  217. #########################################################################
  218. #    task        SendMessage( pReceiverID, pSenderID, pMessage, 
  219. #                                pCreateReplyMailbox, pWaitForSend, 
  220. #                                pWaitForReceipt, pWaitForReply )
  221. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  222. #    Description:    Sends pMessage to pReceiverID by using the AEPost
  223. #                    external tool. All list parameters may contain Boolean, string, 
  224. #                    integer, and list types. This is a synchronous external tool call.
  225. #    Parameters:        pReceiverID:    A non-empty ID list representing the mailbox 
  226. #                                    the message is sent to.
  227. #                    pSenderID:        A non-empty ID list representing the sender 
  228. #                                    of the message.
  229. #                    pMessage:        A list; the contents of the message. Can be empty.
  230. #                    pCreateReplyMailbox:    Boolean, true to create a mailbox with
  231. #                                    ID of pSenderID, which will remain after this 
  232. #                                    call returns. False will not create a mailbox.
  233. #                    pWaitForSend:    Integer, seconds to wait for pReceiver's mailbox 
  234. #                                    to appear. Allows sending a message even when 
  235. #                                    the receiver's mailbox does not exist yet. 
  236. #                                    If pWaitForSend is zero, this task fails if the 
  237. #                                    receiver's mailbox does not exist.
  238. #                    pWaitForReceipt:    Integer, seconds to wait for a receipt from 
  239. #                                        the receiver. A receipt for a message is 
  240. #                                        defined as reversed pSenderID and pReceiverID, 
  241. #                                        with the same internal messageID, and an empty
  242. #                                        content list. If a message is sent with its
  243. #                                        "receiptRequested" flag set, then when it 
  244. #                                        is disposed it creates and sends the receipt.
  245. #                                        If pWaitForReceipt is zero, the message is not 
  246. #                                        marked as "receiptRequested".
  247. #                    pWaitForReply:    Integer, seconds to wait for the first message 
  248. #                                    to pSenderID from pReceiverID. This is assumed
  249. #                                    to be a reply, but it may have been there already.
  250. #                                    If pWaitForReply is zero, this task will just return  
  251. #                                    and report whether the message was sent properly.
  252. #                    NOTE:    The sum of (pWaitForSend + pWaitForReceipt + pWaitForReply)
  253. #                            must not exceed 32767; it is the maximum value for 
  254. #                            the VU 2.1 ExternalToolTimeout() task.
  255. #    Returns:        the AEPost external tool's return list
  256. #    Examples:        SendMessage( {'thisReceiver'}, { 'theSender' }, { 1, true, 5 } );
  257. #                    SendMessage( {'thatReceiver', 5}, { 32, 'theSender' }, 
  258. #                                    { 'hello', true, { 'inner', { 1,2,3 }, true} },  
  259. #                                    false, 20, 0, 20 );
  260. #    Assumptions:    VU 2.1, AEPost
  261. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  262. #    History:
  263. #        04/12/95    SBR            created 
  264. #########################################################################
  265. task SendMessage( pReceiverID, pSenderID, pMessage, pCreateReplyMailbox := false, 
  266.                         pWaitForSend := 0, pWaitForReceipt := 0, pWaitForReply := 0 )
  267. begin
  268.     #println "SendMessage( {pReceiverID}, {pSenderID}, {pMessage}, {pCreateReplyMailbox}, {pWaitForSend}, {pWaitForReceipt}, {pWaitForReply} )";
  269.     
  270.     if not global __gAEPostPresent
  271.         InitMessages();
  272.     
  273.     if pWaitForSend OR pWaitForReceipt OR pWaitForReply
  274.     begin
  275.         tNewTimeout := 10 + pWaitForSend + pWaitForReceipt + pWaitForReply;
  276.         if tNewTimeout > 32767
  277.             tNewTimeout := 32767;
  278.         tSaveTimeout := ExternalToolTimeout(tNewTimeout);
  279.         
  280.         tReturn := AEPost( 'MsgSendThread', pReceiverID, pSenderID, pMessage, 
  281.                                 pCreateReplyMailbox, 
  282.                                 pWaitForSend, pWaitForReceipt, pWaitForReply );
  283.  
  284.         ExternalToolTimeout(tSaveTimeout);
  285.         return tReturn;
  286.     end;
  287.     else
  288.     begin
  289.         return AEPost( 'MsgSend', pReceiverID, pSenderID, pMessage, 
  290.                                 pCreateReplyMailbox );
  291.     end;
  292. end;
  293.  
  294.  
  295. #########################################################################
  296. #    task        ReceiveMessage( pReceiverID, pSenderID, pReceiveMultiple, 
  297. #                                    pDeleteMailbox, pWaitForMessage )
  298. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  299. #    Description:    Receives a message or list of messages.
  300. #    Parameters:        pReceiverID:    A non-empty ID list representing the mailbox 
  301. #                                    that is searched for messages received.
  302. #                    pSenderID:        An ID list representing the expected sender of the 
  303. #                                    message. Use empty list to receive from any sender.
  304. #                    pReceiveMultiple:    Boolean, true to receive all the messages from 
  305. #                                    the expected sender, false to receive only one 
  306. #                                    (oldest message first).
  307. #                    pDeleteMailbox:    Boolean, true to delete the pReceiverID mailbox 
  308. #                                    when this service completes. False to leave the
  309. #                                    mailbox alone.
  310. #                    pWaitForMessage:    Integer, seconds to wait for a message from 
  311. #                                        the sender. If pWaitForReceipt is zero, an 
  312. #                                        error is returned if there is no message.
  313. #                    NOTE: The pWaitForMessage parameter must not exceed 32767; it is the 
  314. #                            maximum value for the VU 2.1 ExternalToolTimeout() task.
  315. #    Returns:        If pSenderID is non-empty and pReceiveMultiple is false:
  316. #                        { message1Contents }
  317. #                    If pSenderID is non-empty and pReceiveMultiple is true:
  318. #                        { {message1Contents}, {message2Contents}... }
  319. #                    If pSenderID is empty and pReceiveMultiple is false:
  320. #                        { pSenderID1, {message1Contents} }
  321. #                    If pSenderID is empty and pReceiveMultiple is true:
  322. #                        {    { pSenderID1, {message1Contents} }, 
  323. #                            { pSenderID1, {message2Contents} },
  324. #                            { pSenderID2, {message3Contents} }... }
  325. #    Examples:        ReceiveMessage( {'theRcvr'}, { 'theSndr' }, false, false, false );
  326. #                    ReceiveMessage( {'thatReceiver', 5}, { }, true, true, 121 );
  327. #    Assumptions:    VU 2.1, AEPost
  328. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  329. #    History:
  330. #        04/12/95    SBR            created 
  331. #########################################################################
  332. task ReceiveMessage( pReceiverID, pSenderID, pReceiveMultiple, pDeleteMailbox := true, 
  333.                         pWaitForMessage := 0 )
  334. begin
  335.     #println "ReceiveMessage( {pReceiverID}, {pSenderID}, {pReceiveMultiple}, {pDeleteMailbox}, {pWaitForMessage} )";
  336.                         
  337.     if not global __gAEPostPresent
  338.         InitMessages();
  339.     
  340.     if pWaitForMessage
  341.     begin
  342.         tNewTimeout := 10 + pWaitForMessage;
  343.         if tNewTimeout > 32767
  344.             tNewTimeout := 32767;
  345.         tSaveTimeout := ExternalToolTimeout(tNewTimeout);
  346.         
  347.         tReturn := AEPost( 'MsgReceiveThread', pReceiverID, pSenderID, 
  348.                                 pReceiveMultiple, pDeleteMailbox,
  349.                                 pWaitForMessage );
  350.  
  351.         ExternalToolTimeout(tSaveTimeout);
  352.         return tReturn;
  353.     end;
  354.     else
  355.     begin
  356.         return AEPost( 'MsgReceive', pReceiverID, pSenderID, 
  357.                                 pReceiveMultiple, pDeleteMailbox );
  358.     end;
  359. end;
  360.  
  361.  
  362. #########################################################################
  363. #    task                    InitMessages(  )
  364. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  365. #    Description:    Determines if the AEPost external tool is running,
  366. #                    and initializes it on the host if it isn't.
  367. #    Parameters:        none
  368. #    Returns:        true if AEPost is available,
  369. #                    false if the tool could not be found, launched or initialized.
  370. #    Examples:        InitMessages();
  371. #    Assumptions:    VU 2.1, AEPost
  372. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  373. #    History:
  374. #        04/12/95    SBR            created based on IsVUAidInstalled()
  375. #########################################################################
  376. task InitMessages( )
  377. begin
  378.     global __gAEPostPresent;
  379.     
  380.     if isUndefined( __gAEPostPresent )
  381.     begin
  382.         AEPostWasInitialized := true;
  383.         test4AEPost := AEPost("Initialize", false);
  384.         theScriptError := ScriptError();
  385.         __gAEPostPresent := (test4AEPost[1] = 0);
  386.         
  387.         if theScriptError = -1223
  388.         begin
  389.             println 'InitMessages: AEPost external tool not found or failed to launch.';
  390.             println 'InitMessages: Copy it to the host hard disk and rebuild the desktop file.';
  391.         end;
  392.         else if theScriptError = -1224
  393.         begin
  394.             println 'InitMessages: External tool launch failed. Is there enough memory?';
  395.         end;
  396.         else if not ( test4AEPost[2] ~= /≈Threading enabled≈/ )
  397.         begin
  398.             println 'InitMessages: Threading is not enabled, please install the Thread Manager';
  399.         end;
  400.     end;
  401.     
  402.     if not __gAEPostPresent
  403.         println "InitMessages: AEPost initialization failed!";
  404.     else
  405.     begin
  406.         println "InitMessages: AEPost free memory is {AEPost("Freememory")}.";
  407.     end;
  408.     
  409.     return __gAEPostPresent;
  410. end;
  411.